
import { _decorator, Component, Node, Vec2, HeightField } from 'cc';
import { BaseItem2D } from '../BaseItem2D';
import { Main } from '../Main';
import { Monster } from '../Monster';
import { Player } from '../Player';
import { BattleMapGrid } from './BattleMapGrid';
const { ccclass, property } = _decorator;



@ccclass('BattleMap')
export class BattleMap extends Component {

	grids:Map<number,Map<number,BattleMapGrid>>=new Map()
	private tmpVec=new Vec2()

	left=0
	right=0
	top=0
	bottom=0
	init(){
		this.left=-Main.I.screenWidth/2-400
		this.right=Main.I.screenWidth/2+400
		this.top=Main.I.screenHeight/2+400
		this.bottom=-Main.I.screenHeight/2-400
	}
	offestX=0
	offsetY=0
	reset(offestX,offsetY){
		this.offestX=offestX
		this.offsetY=offsetY
		let maps=this.grids.values()
		for(let map of maps){
			let values2=map.values()
			for(let grid of values2){
				grid.reset()
			}
			map.clear()
		}
	}
	private mapPool:Map<number,BattleMapGrid>[]=[]
	createMap():Map<number,BattleMapGrid>{
		let map=this.mapPool.pop()
		if(!map){
			map=new Map<number,BattleMapGrid>()
		}
		map['recoverCounter']=0
		return map
	}
	recoverMap(map:Map<number,BattleMapGrid>){
		let values2=map.values()
		for(let grid of values2){
			grid.recover()
		}
		map.clear()
	
		this.mapPool.push(map)
		
	}

	setPlayer(player: Player) {
		let x=player.x-this.offestX
		let y=player.y-this.offsetY
		let width=player.width
		let height=player.height
		let xx1 = Math.floor((x-width/2) / 60)
		let yy1 = Math.floor((y-height/2) / 60)
		let xx2=Math.floor((x+width/2)/60)
		let yy2=Math.floor((y+width/2)/60)
		for(let xx=xx1;xx<=xx2;xx++){
			for(let yy=yy1;yy<=yy2;yy++){
				let grid = this.getGrid(xx, yy)
				grid.player = player
				grid.collisionItems.push(player)
				player.gridList.push(grid)
			}
		}
	}
	setMonster(monster:Monster){
		let x=monster.x-this.offestX
		let y=monster.y-this.offsetY
		if(x<this.left || x>this.right ||y>this.top || y<this.bottom) return //超过屏幕，不处理碰撞

		let width=monster.width
		let height=monster.height
		let xx1 = Math.floor((x-width/2) / 60)
		let yy1 = Math.floor((y-height/2) / 60)
		let xx2=Math.floor((x+width/2)/60)
		let yy2=Math.floor((y+width/2)/60)
		for(let xx=xx1;xx<=xx2;xx++){
			for(let yy=yy1;yy<=yy2;yy++){
				let grid = this.getGrid(xx, yy)
				grid.monsters.push(monster)
				grid.collisionItems.push(monster)
				monster.gridList.push(grid)
			}
		}
	}
	getGrid(xx, yy) {
		if(!this.grids.has(xx)){
			this.grids.set(xx,this.createMap())
		}
		var map=this.grids.get(xx)
		if(!map.has(yy)){
			map.set(yy,BattleMapGrid.create())
		}
		return map.get(yy)
	}


	collisions:Map<BaseItem2D,Set<BaseItem2D>>=new Map()
	//处理角色间的碰撞，在同一个格子中，会分离
	dealCollision(){
		this.collisions.clear()
		let values = this.grids.values()
		for (let map of values) {
			let values2 = map.values()
			for (let grid of values2) {
				if(grid.collisionItems.length>=2){
					let arr=grid.collisionItems
					for(let i=0;i<arr.length;i++){
						for(let j=i+1;j<arr.length;j++){
							let a
							let b
							if(arr[i].id<arr[j].id){
								a=arr[i]
								b=arr[j]
							}else{
								a=arr[j]
								b=arr[i]
							}
							if(!this.collisions.has(a)){
								this.collisions.set(a,new Set<BaseItem2D>())
							}
							let set=this.collisions.get(a)
							set.add(b)
						}
					}
				}
			}
		}
		for(const [a,set] of this.collisions){
			for(const b of set){
				this.dealCollisionSingle(a,b)
			}
		}
	}

	private _tempVec=new Vec2()
	//排开 圆形
	dealCollisionSingle(a:BaseItem2D,b:BaseItem2D){
		let dx=b.x-a.x
		let dy=b.y-a.y
		let l=(a.width+b.width)/2
		let dp=dx*dx+dy*dy
		let lp=l*l
		let dl=lp-dp
		if(dl<=0) return //没有相交
		//排开
		this._tempVec.set(dx,dy)
		this._tempVec.normalize().multiplyScalar((Math.sqrt(lp)-Math.sqrt(dp))/2)
	
		a.separateVec.subtract(this._tempVec)
		b.separateVec.add(this._tempVec)
		// a.setPos(a.x-this._tempVec.x,a.y-this._tempVec.y)
		// b.setPos(b.x+this._tempVec.x,b.y+this.tmpVec.y)
	}

	testHitMonsters(x,y,width,height):Monster[]{
		let x2=x-this.offestX
		let y2=y-this.offsetY
		let res=[]
		if(x2<this.left || x2>this.right || y2>this.top || y2<this.bottom) return res
		let xx1 = Math.floor((x2-width/2) / 60)
		let yy1 = Math.floor((y2-height/2) / 60)
		let xx2=Math.floor((x2+width/2)/60)
		let yy2=Math.floor((y2+width/2)/60)
		for(let xx=xx1;xx<=xx2;xx++){
			for(let yy=yy1;yy<=yy2;yy++){
				let grid = this.getGrid(xx, yy)
				grid.monsters.forEach(monster=>{
					if(monster.isDie) return
					if(!this.rectIntersect(x,y,width,height,monster.x,monster.y,monster.width,monster.height)) return
					res.push(monster)
				})
			}
		}
		return res
	}

	rectIntersect(x1,y1,width1,height1,x2,y2,width2,height2):boolean{
		let dx=Math.abs(x2-x1)
		let dy=Math.abs(y2-y1)
		let mx=((width1+width2)/2-dx)/2 //要分开需要移动的x
		let my=((height1+height2)/2-dy)/2//要分开需要移动的y
		if(mx<=0 || my<=0) return false
		return true
	}

	// //排开 矩形
	// dealCollisionSingle(a:BaseItem2D,b:BaseItem2D){
	// 	//矩形相交了
	// 	let dx=Math.abs(b.x-a.x)
	// 	let dy=Math.abs(b.y-a.y)

	// 	let mx=((a.width+b.width)/2-dx)/2 //要分开需要移动的x
	// 	let my=((a.height+b.height)/2-dy)/2//要分开需要移动的y

	// 	if(mx<=0 || my<=0) return //不需要分开 没有相交

	// 	if(mx<my){//选择移动小的轴来分开
	// 		//以x轴推开
	// 		if(a.x<b.x){
	// 			a.x-=mx
	// 			b.x+=mx
	// 		}else{
	// 			a.x+=mx
	// 			b.x-=mx
	// 		}
		

	// 	}else{
	// 		//以y轴推开
	// 		if(a.y<b.y){
	// 			a.y-=my
	// 			b.y+=my
	// 		}else{
	// 			a.y+=my
	// 			b.y-=my
	// 		}
		
	// 	}
	// }
	
	
}

